/**
 * @file hal_ethernet.h
 * @brief Declares functions that operate on an ethernet device.
 * @author Vamshi Ponnapalli
 */

#ifndef _HAL_ETHERNET
  #define _HAL_ETHERNET
  /*****************************************************************************
   * Includes
   ****************************************************************************/
  #include "hal_types.h"
  #include "hal_defs.h"
  #include "network.h"

  #ifdef __cplusplus
    extern "C" {
  #endif

  /*****************************************************************************
   * Types
   ****************************************************************************/
  /*****************************************************************************
   * Constants
   ****************************************************************************/
  
  /*****************************************************************************
   * Function declarations
   ****************************************************************************/
  /**
   * Initializes the ethernet device.
   */
  void hal_ethernet_initialize(void);
  
  /**
   * Sets the MAC address on the ethernet device. It is assumed that the MAC 
   * address is 6 bytes long.
   *
   * @param macAddress The MAC address to set.
   */
  void hal_ethernet_setMacAddress(mac_address_t macAddress);

  /**
   * Sets the local IP address on the ethernet device. 
   *
   * @param ipAddress The IP address to set.
   */
  void hal_ethernet_setLocalIPAddress(ip_address_t ipAddress);
  
  /**
   * Sets the remote IP address for a specific socket. This ip address will be
   * used when connections are established, or when data is transmitted.
   *
   * @param ipAddress The IP address to set.
   */
  void hal_ethernet_setRemoteIPAddress(ip_address_t ipAddress);

  /**
   * Sets the local port number for the ethernet device. This port number will
   * be used when the ethernet device opens sockets or communicates with other
   * devices.
   *
   * @param portNumber The port number to set.
   */
  void hal_ethernet_setLocalPortNumber(uint16 portNumber);

  /**
   * Sets the remote port number for a specific socket. 
   *
   * @param portNumber The port number to set.
   */
  void hal_ethernet_setRemotePortNumber(uint16 portNumber);

  /**
   * Attempts to open a connection using the ethernet device. The socket must be
   * opened before this is attempted.
   *
   * @param mode The mode to open the socket in. The mode must be one of 
   *             ETHERNET_SOCK_MODE_TCP, ETHERNET_SOCK_MODE_UDP, etc.
   * @param attempts The number of attempts that will be made before which 
   *                 failure is reported.
   * 
   * @return SUCCESS if the operation was completed successfully. FAILED 
   *         otherwise. This will only happen if a connection could not be 
   *         opened after the specified number of attempts.
   */
  uint8 hal_ethernet_connect(uint8 mode, uint8 attempts);  
  
  /**
   * Closes an existing socket.
   *
   */
  void hal_ethernet_closeSocket(void);

  /**
   * Transmits data over the ethernet device.
   *
   * @param data A pointer to the data to be transmitted.
   * @param size The size of the data to be transmitted.
   *
   * @return SUCCESS if the operation was completed successfully, FAILED 
   *         otherwise. Note that a SUCCESS message only means that the steps
   *         for a send operation were completed without error. It does not
   *         indicate that the data was successfully received by the remote 
   *         host.
   */
  uint8 hal_ethernet_transmit(uint8 *pData, uint16 size);
  
  /**
   * Reads a specified number of bytes from the ethernet device.
   *
   * @param data A pointer to the data to be received.
   * @param size The size of the data to be received.
   *
   * @return SUCCESS if the operation was completed successfully, FAILED 
   *         otherwise. 
   */
  uint8 hal_ethernet_receive(uint8 *pData, uint16 size);

  /**
   * Returns the number of bytes that are still to be read from the ethernet 
   * device.
   * 
   * @return The number of bytes that are available for reading.
   */
  uint16 hal_ethernet_getAvailableDataSize(void);

  /**
   * Sets the subnet mask on the ethernet device.
   *
   * @param mask The subnet mask to set.
   */
  void hal_ethernet_setSubnetMask(ip_address_t mask);
  
  /**
   * Sets the gateway IP address on the ethernet device.
   *
   * @param gatewayAddress The IP address of the gateway.
   */
  void hal_ethernet_setGatewayAddress(ip_address_t gatewayAddress);

  #ifdef __cplusplus
    }
  #endif

#endif
